﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Wise.Util
{
     /// <summary>
    /// 正则表达式助手
    /// 集成常见正则表达式
    /// </summary>
    public partial class RegexHelper : HelperBase<RegexHelper>
    {
        public static Regex _NewLine=new Regex (@"[\r|\n]", RegexOptions.Compiled);

        /// <summary>
        /// 检查是否是IP格式
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsIP(string value)
        {
            return instance.doCheckIsIP(value);
        }
        /// <summary>
        /// 检查是否是IP格式
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool HasIP(string value)
        {
            return instance.doCheckHasIP(value);
        }

        /// <summary>
        /// 判断是否是布尔值
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static bool IsBoolen(string requestValue)
        {
            return instance.doIsBoolen(requestValue);
        }

        /// <summary>
        /// 检查Web请求的参数是否含有SQl注入语句或为空，如果包含SQL注入或为空则抛出异常
        /// </summary>
        /// <param name="args"></param>
        public static void CheckWebParamter(params object[] args)
        {
            instance.doCheckWebParamter(args);
        }

        /// <summary>
        /// 判断是否是可执行文件
        /// </summary>
        /// <param name="value">文件后缀名</param>
        /// <returns></returns>
        public static bool IsRunable(string value)
        {
            return instance.doIsRunable(value);
        }


        /// <summary>
        /// 判断是否是整形
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static bool IsInt(string requestValue)
        {
            return instance.doIsInt(requestValue);
        }

        /// <summary>
        /// 判断是否是数值类型
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static bool IsNumber(string requestValue)
        {
            return instance.doIsNumber(requestValue);
        }

        /// <summary>
        /// 获取数值
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static string GetNumber(string requestValue)
        {
            return instance.doGetNumber(requestValue);
        }

        /// <summary>
        /// 从一串字符串中读取数字
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static int? GetIntFromText(string requestValue)
        {
            return instance.doGetIntFromText(requestValue);
        }


        /// <summary>
        /// 检查是否有SQL注入可能性
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static bool HasSql(string requestValue)
        {
            return instance.doCheckHasSql(requestValue);
        }

        /// <summary>
        /// 检查是否有HTML标记的存在
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        public static bool HasHtmlAngleBrackets(string requestValue)
        {
            return instance.doCheckHasAngleBrackets(requestValue);
        }

        /// <summary>
        /// 通过HttpEncoder等手段使SQL注入等失效
        /// </summary>
        /// <param name="requestValue"></param>
        public static void EncodeSqlAndScript(ref string requestValue)
        {
            instance.doEncodeSqlAndScript(ref requestValue);
        }

        /// <summary>
        /// 判断字符串是否是Uri
        /// </summary>
        /// <returns></returns>
        public static bool IsUri(string value)
        {
            return instance.doIsUri(value);
        }


        /// <summary>
        /// 判断是否是GUID
        /// </summary>
        /// <returns></returns>
        public static bool IsGuid(string parter)
        {
            return instance.doIsGuid(parter);
        }


        /// <summary>
        /// 判断字符串是否是自然日期类型（包含简体公历、简体农历）
        /// </summary>
        /// <returns></returns>
        public static bool IsNaturalDateTime(string value)
        {
            return instance.doIsNaturalDateTime(value);
        }

        /// <summary>
        /// 判断字符串是否是日期类型
        /// </summary>
        /// <returns></returns>
        public static bool IsDateTime(string value)
        {
            return instance.doIsDateTime(value);
        }

        /// <summary>
        /// 判断字符串是否是短日期类型
        /// </summary>
        /// <returns></returns>
        public static bool IsDate(string value)
        {
            return instance.doIsDate(value);
        }

        /// <summary>
        /// 判断输入值是否只含有英文
        /// 空格、null都算全英文
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsEnglishOnly(string value)
        {
            return instance.doIsEnglishOnly(value);
        }

        /// <summary>
        /// 检查字符串是否已加密
        /// 只适用于3DES、DES
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsEncrypted(string value)
        {
            if (string.IsNullOrEmpty(value))
                return false;
            try
            {
                Convert.FromBase64String(value);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 判断字符串是否是时间类型
        /// </summary>
        /// <returns></returns>
        public static bool IsTime(string value)
        {
            return instance.doIsTime(value);
        }



        /// <summary>
        /// 判断字符串是否是时间间隔类型
        /// </summary>
        /// <returns></returns>
        public static bool IsTimeSpan(string value)
        {
            return instance.doIsTimeSpan(value);
        }

        /// <summary>
        /// 获取注释文本
        /// </summary>
        /// <param name="value">要检索的文本</param>
        /// <param name="isFromFirstChar">是否从第一个字符开始</param>
        /// <returns></returns>
        public static string GetComment(string value, bool isFromFirstChar)
        {
            return instance.doGetComment(value, isFromFirstChar);
        }

        /// <summary>
        /// 判断是否是Javascript null 或 undefined
        /// </summary>
        /// <param name="parter"></param>
        /// <returns></returns>
        public static bool IsJsNull(string parter)
        {
            return instance.doIsJsNull(parter);
        }

        /// <summary>
        /// 简易将客户端或浏览器不可直接使用的尖括号，引号、回车、换行、制表符等转换成类似效果
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string HtmlEncode(string value)
        {
            return instance.doHtmlEncode(value);
        }

        /// <summary>
        /// 判断是邮件格式
        /// </summary>
        /// <returns></returns>
        public static bool IsEmail(string value)
        {
            return instance.doIsEmail(value);
        }

        /// <summary>
        /// 判断输入值是否可以作为布尔值的 真值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        internal static bool IsTrue(string value)
        {
            return instance.doIsTrue(value);
        }

        internal static bool IsWordsOnly(string value)
        {
            return instance.doIsWordsOnly(value);
        }

    }

    /// <summary>
    /// 所有未静态并编译的正则表达式 存在争议或BUG
    /// </summary>
    public partial class RegexHelper
    {
        Regex _REG_IS_NOT_TRUE = new Regex("[未|不|false|0|离]"
            , RegexOptions.Compiled | RegexOptions.IgnoreCase);
        protected virtual bool doIsTrue(string value)
        {
            return !string.IsNullOrEmpty(value) && !_REG_IS_NOT_TRUE.IsMatch(value);
        }
        Regex _REG_IS_WORDS = new Regex(@"^[\w|\d|\s]+$", RegexOptions.Multiline | RegexOptions.Compiled);
        protected virtual bool doIsWordsOnly(string value)
        {
            return !string.IsNullOrEmpty(value) && _REG_IS_WORDS.IsMatch(value);
        }
        /// <summary>
        /// 判断是否是可执行文件
        /// </summary>
        /// <param name="value">文件后缀名</param>
        /// <returns></returns>
        private bool doIsRunable(string value)
        {
            //Mac可执行文件格式为Mach-O即Mach Object格式。
            //Linux可执行文件格式为ELF即Executable and Linkable Format。
            return new Regex(@"\.?exe|cmd|com|bat|sys|ELF|Mach-O", RegexOptions.IgnoreCase).IsMatch(value);
        }

        private bool doIsUri(string value)
        {
            return Uri.IsWellFormedUriString(value, UriKind.RelativeOrAbsolute);
            //^([a-z0-9+.-]+):(?://(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*)@)?((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*)(?::(\d*))?(/(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?|(/?(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})+(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?)(?:\?((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?$/i


            //下面这条在测试不是Uri格式的时候会抛出异常
            //return Regex.IsMatch(@"^([a-zA-Z0-9+.-]+):(//([a-zA-Z0-9-._~!$&'()*+,;=:]*)@)?([a-zA-Z0-9-._~!$&'()*+,;=]+)(:(\\d*))?(/?[a-zA-Z0-9-._~!$&'()*+,;=:/]+)?(\\?[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?(#[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?$(:(\\d*))?(/?[a-zA-Z0-9-._~!$&'()*+,;=:/]+)?(\?[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?(\#[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?$", value);
        }


        internal Regex _REG_JS_NULL = new Regex(@"^\s*null|undefined\s*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// 判断是否是Javascript null 或 undefined
        /// </summary>
        /// <param name="parter"></param>
        /// <returns></returns>
        protected virtual bool doIsJsNull(string parter)
        {
            return _REG_JS_NULL.IsMatch(parter);
        }



        internal Regex _REG_BOOLEN = new Regex(@"^\s*true|false\s*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// 判断是否是布尔值
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual bool doIsBoolen(string requestValue)
        {
            if (requestValue == null) return false;
            return _REG_BOOLEN.IsMatch(requestValue);
        }

        internal Regex _REG_INT = new Regex(@"^\s*[0-9]+\s*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// 判断是否是整形
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual bool doIsInt(string requestValue)
        {

            if (requestValue == null) return false;
            return _REG_INT.IsMatch(requestValue);
        }

        internal Regex _REG_ALL_Number = new Regex(@"^\s*[\+\-]?[0-9]+(\.[0-9]+)*\s*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// 判断是否是数值类型
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual bool doIsNumber(string requestValue)
        {
            if (requestValue == null) return false;
            return _REG_ALL_Number.IsMatch(requestValue);
        }
        


        internal Regex _REG_Number = new Regex(@"[\+\-]?[0-9]+(\.[0-9]+)*", RegexOptions.Compiled);

        /// <summary>
        /// 获取数值
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual string doGetNumber(string requestValue)
        {
            if (requestValue == null) return string.Empty;
            Match match = _REG_Number.Match(requestValue);
            if (match == null)
            {
                return null;
            }
            else
            {
                return match.Value;
            }
        }

        protected virtual int? doGetIntFromText(string requestValue)
        {
            var mc = _Reg_Number_With_Chinese.Match(requestValue);
            if (mc.Success)
            {
                string val = mc.Value;
                if (_REG_Number.IsMatch(val))
                {
                    return (int)decimal.Parse(val);
                }
                else
                {
                    return (int)NumberConventer.ChnToArab(val);
                }
            }
            return null;
        }


        /// <summary>
        /// 阿拉伯数字转中文数字，中文数字转阿拉伯数字。
        /// by hcling97.Net 2007.03
        /// </summary>
        public class NumberConventer
        {
            static string[] ArabinNum = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            static string[] ChnNum = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "百", "千", "万", "亿" };

            static string[] Union = { "", "十", "百", "千" };

            public static string ArabToChn(Decimal ArabNum, out string msg)
            {
                string neg = string.Empty;
                neg = (ArabNum < 0) ? "负" : "";
                string result = string.Empty;
                string[] part =
                (ArabNum.ToString().Replace("-", string.Empty)).Split('.');
                Int64 temp = Convert.ToInt64(part[0]);
                Int64 epart = temp;
                string dotpart =
                (part.Length > 1) ? part[1] : string.Empty;
                if (part.Length > 1)
                {
                    dotpart = GetDotPart(dotpart);
                }
                string tmp = string.Empty;
                string lasttemp = string.Empty;
                for (int i = 0; i <= ((epart.ToString().Length - 1) / 4); i++)
                {
                    int thousand = 0;
                    thousand = Convert.ToInt32(temp %
                    10000);
                    temp = temp / 10000;
                    lasttemp = tmp;
                    tmp = GetThousandPart(thousand);

                    if (i == 0)
                    {
                        result = tmp;
                        lasttemp = tmp;
                    }
                    if (i == 1)//返回的是万
                    {
                        if (result == "零")
                        {
                            result = string.Empty;
                        }
                        result = tmp + "万" +
                        ((lasttemp.IndexOf("千") == -1 && lasttemp != "零") ? "零" : "") + result;
                    }
                    if (i == 2)//亿
                    {
                        if (result.IndexOf("零万") != -1)
                        {

                            result = result.Replace("零万", string
                            .Empty);
                        }
                        result = tmp + "亿" +
                ((lasttemp.IndexOf("千") == -1 && lasttemp != "零") ? "零" : "") + result;
                    }
                    if (i == 3)//万亿
                    {
                        if (result.IndexOf("零亿") != -1)
                        {
                            result = result.Replace("零亿", "亿");
                        }
                        result = tmp + "万" +
                        ((lasttemp.IndexOf("千") == -1 && lasttemp != "零") ? "零" : "") + result;
                    }
                    if (i == 4)//亿亿
                    {
                        if (result.IndexOf("零万") != -1)
                        {

                            result = result.Replace("零万", string.Empty);
                        }
                        result = tmp + "亿" +
                        ((lasttemp.IndexOf("千") == -1 && lasttemp != "零") ? "零" : "") + result;
                    }
                }
                result = neg + result + dotpart;
                msg = "成功转换！";
                return result;

            }

            /// <summary>
            　　　　/// 处理小数部分
            　　　　/// </summary>
            　　　　/// <param name="dotPart"></param>
            　　　　/// <returns></returns>
            static string GetDotPart(string dotPart)
            {
                string result = "点";
                for (int i = 0; i < dotPart.Length; i++)
                {

                    result += ChnNum[Convert.ToInt32(dotPart[
                    i].ToString())];
                }
                for (int j = 0; j < result.Length; j++)
                //去除无效零或点
                {

                    if (result[result.Length - j - 1].ToString()
                    != "点" && result[result.Length - j - 1].ToString() != "零")
                    {
                        break;
                    }
                    else
                    {
                        result =
                        result.Substring(0, (result.Length - j - 1
                        ));
                    }
                }
                return result;
            }

            /// <summary>
            　　　　/// 万位以下的分析
            　　　　/// </summary>
            　　　　/// <returns></returns>
            static string GetThousandPart(int number)
            {
                if (number == 0)
                {
                    return "零";
                }
                string result = string.Empty;
                bool lowZero = false;
                //记录低位有没有找到非零值，没找到置true
                bool befZero = false;
                //记录前一位是不是非零值，是0则置true
                int temp = number;
                int index = number.ToString().Length;
                for (int i = 0; i < index; i++)
                {
                    int n = temp % 10;
                    temp = temp / 10;
                    if (i == 0) //起始位
                    {
                        if (n == 0)
                        {
                            lowZero = true; //低位有0
                            befZero = true; //前位为0
                        }
                        else
                        {
                            result = ChnNum[n];
                        }
                    }
                    else
                    {
                        if (n != 0)
                        {
                            result = ChnNum[n] + Union[i] + result;
                            lowZero = false;
                            befZero = false;
                        }
                        else
                        {
                            if (!lowZero)
                            {
                                if (!befZero)
                                //低位有数，且前位不为0，本位为0填零
                                //eg.5906
                                {
                                    result = ChnNum[n] + result;
                                    befZero = true;
                                }
                                else
                                //低位有数，且前位为0省略零eg. 5008
                                {
                                }
                            }
                            else //低位为0
                            {
                                if (!befZero)//理论上不存在eg 5080
                                {
                                    result = ChnNum[n] + result;
                                    befZero = true;
                                }
                                else //eg. 5000
                                {
                                }
                            }
                        }
                    }
                }
                return result;
            }

            public static Decimal ChnToArab(string ChnNum)
            {
                Decimal result = 0;
                string temp = ChnNum;
                bool neg = false;
                if (ChnNum.IndexOf("负") != -1)
                {
                    neg = true;
                    temp = temp.Replace("负", string.Empty);
                }
                string pre = string.Empty;
                string abo = string.Empty;
                temp = temp.Replace("点", ".");
                string[] part = temp.Split('.');
                pre = part[0];
                Decimal dotPart = 0;
                if (part.Length > 1)
                {
                    abo = part[1];
                    dotPart = GetArabDotPart(abo);
                }

                int yCount = 0;
                //"亿"的个数，有可能出现亿亿。
                //int yPos = 0;

                int index = 0;
                while (index < pre.Length)
                {
                    if (pre.IndexOf("亿", index) != -1)
                    {
                        yCount++;
                        //yPos = pre.IndexOf("亿",index);
                        index = pre.IndexOf("亿", index) + 1;
                    }
                    else
                    {
                        break;
                    }
                }
                if (yCount == 2)//亿亿
                {
                    pre = pre.Replace("亿", ",");
                    string[] sp = pre.Split(',');
                    result =(neg ? -1 : 1) * ((HandlePart(sp[0]) * 10000000000000000) + (HandlePart(sp[1])* 100000000) + HandlePart(sp[2])) + dotPart;
                }
                else
                {
                    if (yCount == 1)
                    {
                        pre = pre.Replace("亿", ",");
                        string[] sp = pre.Split(',');
                        result =
                        (neg ? -1 : 1) * ((HandlePart(sp[0]) * 100000000) + HandlePart(sp[1])) + dotPart;
                    }
                    else
                    {
                        if (yCount == 0)
                        {
                            result =
                            (neg ? -1 : 1) * HandlePart(pre) + dotPart;
                        }
                    }
                }
                return result;

            }

            /// <summary>
            /// 处理亿以下内容。
            /// </summary>
            /// <param name="num"></param>
            /// <returns></returns>
            static Decimal HandlePart(string num)
            {
                Decimal result = 0;
                string temp = num;
                temp = temp.Replace("万", ",");
                string[] part = temp.Split(',');
                for (int i = 0; i < part.Length; i++)
                {
                    result += Convert.ToDecimal(GetArabThousandPart(part[part.Length - i - 1])) * Convert.ToDecimal((System.Math.Pow(10000, Convert.ToDouble(i))));
                }
                return result;
            }

            /// <summary>
            　　　　/// 取得阿拉伯数字小数部分。
            　　　　/// </summary>
            　　　　/// <returns></returns>
            static Decimal GetArabDotPart(string dotpart)
            {
                Decimal result = 0.00M;
                string spe = "0.";
                for (int i = 0; i < dotpart.Length; i++)
                {
                    spe += switchNum(dotpart[i].ToString()).ToString();
                }
                result = Convert.ToDecimal(spe);
                return result;
            }

            public static int GetArabThousandPart(string number)
            {

                string ChnNumString = number;
                if (ChnNumString == "零")
                {
                    return 0;
                }
                if (ChnNumString != string.Empty)
                {
                    if (ChnNumString[0].ToString() == "十")
                    {
                        ChnNumString = "一" + ChnNumString;
                    }
                }

                ChnNumString = ChnNumString.Replace("零", string.Empty);
                //去除所有的零
                int result = 0;
                int index = ChnNumString.IndexOf("千");
                if (index != -1)
                {
                    result += switchNum(ChnNumString.Substring(0, index)) * 1000;
                    ChnNumString =
                    ChnNumString.Remove(0, index + 1);
                }
                index = ChnNumString.IndexOf("百");
                if (index != -1)
                {
                    result += switchNum(ChnNumString.Substring(0, index)) * 100;
                    ChnNumString =
                    ChnNumString.Remove(0, index + 1);
                }
                index = ChnNumString.IndexOf("十");
                if (index != -1)
                {
                    result += switchNum(ChnNumString.Substring(0, index)) * 10;
                    ChnNumString = ChnNumString.Remove(0, index + 1);
                }
                if (ChnNumString != string.Empty)
                {
                    result += switchNum(ChnNumString);
                }
                return result;
            }

            /// <summary>
            　　　　/// 取得汉字对应的阿拉伯数字
            　　　　/// </summary>
            　　　　/// <param name="n"></param>
            　　　　/// <returns></returns>
            static int switchNum(string n)
            {
                switch (n)
                {
                    case "零":
                        {
                            return 0;
                        }
                    case "一":
                        {
                            return 1;
                        }
                    case "二":
                        {
                            return 2;
                        }
                    case "三":
                        {
                            return 3;
                        }
                    case "四":
                        {
                            return 4;
                        }
                    case "五":
                        {
                            return 5;
                        }
                    case "六":
                        {
                            return 6;
                        }
                    case "七":
                        {
                            return 7;
                        }
                    case "八":
                        {
                            return 8;
                        }
                    case "九":
                        {
                            return 9;
                        }
                    default:
                        {
                            return -1;
                        }
                }
                return -1;
            }
        }

        private Regex _Reg_Number_With_Chinese = new Regex(@"\d+|[零|一|二|三|四|五|六|七|八|九|十|点]", RegexOptions.Compiled);

        /// <summary>
        /// SQL语句
        /// </summary>
        private Regex _regHasSQL = new Regex(@"\-\-|\'|delete\s|drop\s|exec\s+|execute\s+|waitfor|\/\*|\*\/", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// 检查是否有SQL注入可能性
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual bool doCheckHasSql(string requestValue)
        {
            if (requestValue == null) return false;
            return _regHasSQL.IsMatch(requestValue);
        }


        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement1 = new Regex(@"\-\-", RegexOptions.Compiled);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement2 = new Regex(@"\/\*", RegexOptions.Compiled);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement3 = new Regex(@"\*\/", RegexOptions.Compiled);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement4 = new Regex(@"'", RegexOptions.Compiled);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement5 = new Regex(@"<", RegexOptions.Compiled);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement6 = new Regex(@"sys\.", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement7 = new Regex(@"exec\s|execute\s", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement8 = new Regex(@"drop\s", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _SQLStatement9 = new Regex(@"delete\s", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        /// <summary>
        /// 通过HttpEncoder等手段使SQL注入、脚本注入等失效
        /// </summary>
        /// <param name="requestValue"></param>
        protected virtual void doEncodeSqlAndScript(ref string requestValue)
        {
            //使用Unicode替换无效
            if (_regHasSQL.IsMatch(requestValue))
            {
                requestValue = _SQLStatement1.Replace(requestValue, " - - ");
                requestValue = _SQLStatement2.Replace(requestValue, " / * ");
                requestValue = _SQLStatement3.Replace(requestValue, " * / ");
                requestValue = _SQLStatement4.Replace(requestValue, "’");
                requestValue = _SQLStatement6.Replace(requestValue, "ｓｙｓ。");
                requestValue = _SQLStatement7.Replace(requestValue, "ｅｘｅｃ　");
                requestValue = _SQLStatement8.Replace(requestValue, "ｄｒｏｐ　");
                requestValue = _SQLStatement9.Replace(requestValue, "ｄｅｌｅｔｅ　");
            }
            doEncodeScript(ref requestValue);
        }


        protected virtual void doEncodeScript(ref string requestValue)
        {
            if (_HasHtmlAngleBrackets.IsMatch(requestValue))
            {
                requestValue = _SQLStatement5.Replace(requestValue, "&lt;");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected internal Regex _HasHtmlAngleBrackets = new Regex(@"\<\w+|\w+\>", RegexOptions.Compiled);


        /// <summary>
        /// 检查是否有脚本的存在
        /// </summary>
        /// <param name="requestValue"></param>
        /// <returns></returns>
        protected virtual bool doCheckHasAngleBrackets(string requestValue)
        {
            return requestValue != null && _HasHtmlAngleBrackets.IsMatch(requestValue);
        }

        /// <summary>
        /// 检查Web请求的参数是否含有SQl注入语句或为空，如果包含SQL注入或为空则抛出异常
        /// </summary>
        /// <param name="args"></param>
        protected virtual void doCheckWebParamter(params object[] args)
        {
            foreach (object obj in args)
            {
                if (obj == null)
                {
                    throw new ArgumentNullException();
                }
                else if (obj is string)
                {
                    string value = obj.ToString();
                    if (instance.doCheckHasSql(value) || instance.doCheckHasAngleBrackets(value))
                    {
                        throw new ArgumentException("SQL 注入攻击或包含脚本语句");
                    }
                }
            }
        }
        private Regex _regIsIpV4 = new Regex(@"^(\d{1,3}\.){3}(\d{1,3})$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private Regex _regIsIpV6 = new Regex(@"^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private Regex _regHasIpV4 = new Regex(@"(\d{1,3}\.){3}(\d{1,3})", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private Regex _regHasIpV6 = new Regex(@"\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*", RegexOptions.Compiled | RegexOptions.IgnoreCase);

        /// <summary>
        /// 检查是否是IP信息
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doCheckIsIP(string value)
        {
            if (string.IsNullOrEmpty(value)) return false;
            return _regIsIpV4.IsMatch(value) || _regIsIpV6.IsMatch(value);
        }

        /// <summary>
        /// 检查是否有IP信息
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doCheckHasIP(string value)
        {
            if (string.IsNullOrEmpty(value)) return false;
            return this._regHasIpV4.IsMatch(value) || this._regHasIpV6.IsMatch(value);
        }


        /// <summary>
        /// 使用正则表达式判断是否为日期
        /// </summary>
        protected virtual bool doIsNaturalDateTime(string str)
        {
            bool isDateTime = false;
            // yyyy/MM/dd
            if (Regex.IsMatch(str, "^(?<year>\\d{2,4})/(?<month>\\d{1,2})/(?<day>\\d{1,2})$"))
                isDateTime = true;
            // yyyy-MM-dd 
            else if (Regex.IsMatch(str, "^(?<year>\\d{2,4})-(?<month>\\d{1,2})-(?<day>\\d{1,2})$"))
                isDateTime = true;
            // yyyy.MM.dd 
            else if (Regex.IsMatch(str, "^(?<year>\\d{2,4})[.](?<month>\\d{1,2})[.](?<day>\\d{1,2})$"))
                isDateTime = true;
            // yyyy年MM月dd日
            else if (Regex.IsMatch(str, "^((?<year>\\d{2,4})年)?(?<month>\\d{1,2})月((?<day>\\d{1,2})日)?$"))
                isDateTime = true;
            // yyyy年MM月dd日
            else if (Regex.IsMatch(str, "^((?<year>\\d{2,4})年)?(正|一|二|三|四|五|六|七|八|九|十|十一|十二)月((一|二|三|四|五|六|七|八|九|十){1,3}日)?$"))
                isDateTime = true;

            // yyyy年MM月dd日
            else if (Regex.IsMatch(str, "^(零|〇|一|二|三|四|五|六|七|八|九|十){2,4}年((正|一|二|三|四|五|六|七|八|九|十|十一|十二)月((一|二|三|四|五|六|七|八|九|十){1,3}(日)?)?)?$"))
                isDateTime = true;
            // yyyy年
            //else if (Regex.IsMatch(str, "^(?<year>\\d{2,4})年$"))
            //    isDateTime = true;

            // 农历1
            else if (Regex.IsMatch(str, "^(甲|乙|丙|丁|戊|己|庚|辛|壬|癸)(子|丑|寅|卯|辰|巳|午|未|申|酉|戌|亥)年((正|一|二|三|四|五|六|七|八|九|十|十一|十二)月((一|二|三|四|五|六|七|八|九|十){1,3}(日)?)?)?$"))
                isDateTime = true;
            // 农历2
            else if (Regex.IsMatch(str, "^((甲|乙|丙|丁|戊|己|庚|辛|壬|癸)(子|丑|寅|卯|辰|巳|午|未|申|酉|戌|亥)年)?(正|一|二|三|四|五|六|七|八|九|十|十一|十二)月初(一|二|三|四|五|六|七|八|九|十)$"))
                isDateTime = true;

            // XX时XX分XX秒
            else if (Regex.IsMatch(str, "^(?<hour>\\d{1,2})(时|点)(?<minute>\\d{1,2})分((?<second>\\d{1,2})秒)?$"))
                isDateTime = true;
            // XX时XX分XX秒
            else if (Regex.IsMatch(str, "^((零|一|二|三|四|五|六|七|八|九|十){1,3})(时|点)((零|一|二|三|四|五|六|七|八|九|十){1,3})分(((零|一|二|三|四|五|六|七|八|九|十){1,3})秒)?$"))
                isDateTime = true;
            // XX分XX秒
            else if (Regex.IsMatch(str, "^(?<minute>\\d{1,2})分(?<second>\\d{1,2})秒$"))
                isDateTime = true;
            // XX分XX秒
            else if (Regex.IsMatch(str, "^((零|一|二|三|四|五|六|七|八|九|十){1,3})分((零|一|二|三|四|五|六|七|八|九|十){1,3})秒$"))
                isDateTime = true;

            // XX时
            else if (Regex.IsMatch(str, "\\b(?<hour>\\d{1,2})(时|点钟)\\b"))
                isDateTime = true;
            else
                isDateTime = false;

            return isDateTime;
        }

        /// <summary>
        /// 判断字符串是否是日期类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doIsDateTime(string value)
        {
            if (String.IsNullOrEmpty(value))
                return false;
            return _DATE_TIME_1.IsMatch(value)
                || _DATE_TIME_2.IsMatch(value)
                || _DATE_TIME_3.IsMatch(value)
                || _DATE_TIME_4.IsMatch(value)
                || _DATE_TIME_5.IsMatch(value)
                || _DATE_TIME_6.IsMatch(value);

                //@"^(((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d)$");
        }

        static Regex _DATE_TIME_1 = new Regex(@"^\d{4}\-\d{2}\-\d{2}", RegexOptions.Compiled);
        static Regex _DATE_TIME_2 = new Regex(@"^\d{4}\\\d{2}\\\d{2}", RegexOptions.Compiled);
        static Regex _DATE_TIME_3 = new Regex(@"^\d{4}\/\d{2}\/\d{2}", RegexOptions.Compiled);
        static Regex _DATE_TIME_4 = new Regex(@"^\d{2}\-\d{2}\-\d{4}", RegexOptions.Compiled);
        static Regex _DATE_TIME_5 = new Regex(@"^\d{2}\\\d{2}\\\d{4}", RegexOptions.Compiled);
        static Regex _DATE_TIME_6 = new Regex(@"^\d{2}\/\d{2}\/\d{4}", RegexOptions.Compiled);

        static Regex _DATE_1 = new Regex(@"^\d{4}\-\d{2}\-\d{2}$", RegexOptions.Compiled);
        static Regex _DATE_2 = new Regex(@"^\d{4}\\\d{2}\\\d{2}$", RegexOptions.Compiled);
        static Regex _DATE_3 = new Regex(@"^\d{4}\/\d{2}\/\d{2}$", RegexOptions.Compiled);
        static Regex _DATE_4 = new Regex(@"^\d{2}\-\d{2}\-\d{4}$", RegexOptions.Compiled);
        static Regex _DATE_5 = new Regex(@"^\d{2}\\\d{2}\\\d{4}$", RegexOptions.Compiled);
        static Regex _DATE_6 = new Regex(@"^\d{2}\/\d{2}\/\d{4}$", RegexOptions.Compiled);

        /// <summary>
        /// 判断字符串是否是短日期类型
        /// </summary>
        /// <returns></returns>
        protected virtual bool doIsDate(string value)
        {
            if (String.IsNullOrEmpty(value))
                return false;
            return _DATE_1.IsMatch(value)
                || _DATE_2.IsMatch(value)
                || _DATE_3.IsMatch(value)
                || _DATE_4.IsMatch(value)
                || _DATE_5.IsMatch(value)
                || _DATE_6.IsMatch(value);
            //return Regex.IsMatch(value, @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");
        }

        /// <summary>
        /// 判断字符串是否是时间类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doIsTime(string value)
        {
            return Regex.IsMatch(value, @"^((20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d)$");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doIsTimeSpan(string value)
        {
            return Regex.IsMatch(value, @"^\d{2}\:\d{2}\:\d{2}\.\d{7}$");
        }

        internal Regex _regIsGuid =
            new Regex(@"^([0-9|a-f|A-F]{32})|([0-9|a-f|A-F]{8}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{12})|(\{[0-9|a-f|A-F]{8}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{12}\})|(\([0-9|a-f|A-F]{8}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{4}-[0-9|a-f|A-F]{12}\))|(\{0x[0-9|a-f|A-F]{8}\s*\,\s*0x[0-9|a-f|A-F]{4}\s*\,\s*0x[0-9|a-f|A-F]{4}\s*\,\s*{\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\,\s*0x[0-9|a-f|A-F]{2}\s*\}\s*\})$", RegexOptions.Compiled);

        /// <summary>
        /// 判断是否是GUID
        /// </summary>
        /// <returns></returns>
        protected virtual bool doIsGuid(string parter)
        {
            return _regIsGuid.IsMatch(parter);
        }

        /// <summary>
        /// 获取注释
        /// </summary>
        /// <returns></returns>
        protected virtual string doGetComment(string value, bool isFromFirstChar)
        {
            if (isFromFirstChar)
            {
                Match mc = _REG_Get_Comment.Match(value);
                return mc.Success ? mc.Value : null;
            }
            else
            {
                Match mc = _REG_Has_Comment.Match(value);
                return mc.Success ? mc.Value : null;
            }
        }
        /**/
        internal Regex _REG_Has_Comment = new Regex("(?<!:)\\/\\/.*|\\/\\*(\\s|.)*?\\*\\/");

        /// <summary>
        /// 用于从第一个字符开始搜索注释
        /// </summary>
        internal Regex _REG_Get_Comment = new Regex("^(?<!:)\\/\\/.*|\\/\\*(\\s|.)*?\\*\\/");


        Regex regNewLine = new Regex(@"\r\n", RegexOptions.Compiled);

        public static Regex DEFAULT_REG_Space = new Regex(@"\r|\t|\n", RegexOptions.Compiled);

        protected virtual string doHtmlEncode(string value)
        {
            value = regNewLine.Replace(value, "<br/>");
            value = DEFAULT_REG_Space.Replace(value, "  ");
            value = value.Replace('\"', '”').Replace('\'', '‘');
            doEncodeScript(ref value);
            return value.Trim();
        }

        /// <summary>
        /// 判断输入值是否只含有英文
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected virtual bool doIsEnglishOnly(string value)
        {
            return string.IsNullOrEmpty(value)
                || regIsEnglish.IsMatch(value);
        }

        Regex regIsEnglish = new Regex(@"^[a-zA-Z\d\-_\+\*\.\,\'\;\:\!\s\%\$\#\@\&\^\<\>]+$", RegexOptions.Compiled);

        Regex regIsEmail = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$", RegexOptions.IgnoreCase);
        /// <summary>
        /// 判断是邮件格式
        /// </summary>
        /// <returns></returns>
        protected virtual bool doIsEmail(string value)
        {
            return value != null && regIsEmail.IsMatch(value);
        }
    }

}
